package com.zcyr.core;

import com.zcyr.exception.DatabaseEnvironmentException;
import com.zcyr.exception.DatabaseEnvironmentManagerException;
import com.zcyr.pojo.DatabaseEnvironmentInfo;
import org.springframework.beans.factory.InitializingBean;

import java.util.Collection;
import java.util.Map;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public abstract class AbstractDatabaseEnvironmentManager implements IDatabaseEnvironmentManager, InitializingBean, VisualEnvironmentManager {
    private final Map<String, DatabaseEnvironmentInfo> databaseEnvironmentInfoMap = new ConcurrentHashMap<>();
    private final Queue<AbstractDatabaseEnvironment> errorEnvironmentQue = new ConcurrentLinkedQueue<>();

    @Override
    public void afterPropertiesSet() throws Exception {
        this.init();
    }

    protected void init() throws DatabaseEnvironmentException {}

    protected AbstractDatabaseEnvironment pollErrorEnvironment(){
        return errorEnvironmentQue.poll();
    }

    protected void addErrorEnvironment(AbstractDatabaseEnvironment environment){
        errorEnvironmentQue.add(environment);
    }

    /**
     * 反馈出现错误的环境, 并处理.
     * @param environment 异常环境
     */
    public AbstractDatabaseEnvironment reportErrorEnvironment(AbstractDatabaseEnvironment environment) throws DatabaseEnvironmentManagerException {
        return null;
    }

    @Override
    public abstract AbstractDatabaseEnvironment getEnvironment(String uuid);

    @Override
    public abstract AbstractDatabaseEnvironment getAvailableEnvironment() throws DatabaseEnvironmentManagerException;

    public int getEnvironmentInfoMapSize(){
        return databaseEnvironmentInfoMap.size();
    }

    public Collection<DatabaseEnvironmentInfo> getAllInfo(){
        return databaseEnvironmentInfoMap.values();
    }

    protected void registerEnvironmentInfo(DatabaseEnvironmentInfo info){
        databaseEnvironmentInfoMap.put(info.getId(), info);
    }

    protected void removeEnvironmentInfo(DatabaseEnvironmentInfo info){
        databaseEnvironmentInfoMap.remove(info.getId());
    }

    public String generateUUID(){
        return UUID.randomUUID().toString().replace("-", "");
    }

    protected AbstractDatabaseEnvironment newDatabaseEnvironment(DatabaseEnvironmentInfo info) throws DatabaseEnvironmentManagerException {
        throw new DatabaseEnvironmentManagerException("TODO newDatabaseEnvironment()");
    }

    @Override
    public abstract void releaseDatabaseEnvironment(String uuid) throws DatabaseEnvironmentManagerException;

    /**
     * 为环境续期
     */
    public abstract void renewal(String uuid);
}
